﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace CEED.Utils
{
    public enum MediaType
    {
        INNER_DEVICE,
        CARD1,
        CARD2,
        EXTENDED_DEVICE
    };
    public enum FlagIndex
    {
        MEDIA_CARD_DEVICE = 3,
        MEDIA_PLATFORM_INDEX,
        MEDIA_TYPE_INDEX,
        MEDIA_UNIT_SIZE
    };
    [StructLayout(LayoutKind.Sequential, Pack = 1)] //, Size = 0x330
    public struct CCICXIEntry
    {
        public uint Offset;
        public uint Length;
    }
    public struct TitleID
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] ID;
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)] //, Size = 0x330
    public struct NcsdHeader
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
        public byte[] NCSDHeaderSignature;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public char[] Magic;
        public uint CCILength;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] MainTitleID;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] PartitionFStype;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] PartitionCrypttype;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public CCICXIEntry[] CXIEntries;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
        public byte[] ExHeaderHash;

        public uint AdditionalHeaderSize;
        public uint SectorZeroOffset;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Flags;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public TitleID[] NCCHTitleIDs;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x30)]
        public byte[] Reserved_0;

        // Card Info Header
        public uint WritableRegionAddress;

        public uint CardInfoBitmask;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xF8)]
        public byte[] Reserved_1;

        // Production "makerom" notes start 
        public uint UsedRomLength; //in bytes

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1C)]
        public byte[] Reserved_2;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] CVerTitleId;
        public UInt16 CVerTitleVersion;
        // Production "makerom" notes end
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xCD6)]
        public byte[] Reserved_3;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x8)]
        public byte[] MediaID;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x8)]
        public byte[] Reserved_4;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x30)]
        public byte[] InitialData;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xC0)]
        public byte[] Reserved_5;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
        public byte[] cxi_Header;

        // Dev Card Info Header
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)]
        public byte[] CardDeviceReserved1;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
        public byte[] TitleKey;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xF0)]
        public byte[] CardDeviceReserved2;
    }

    public class NCSD
    {
        public NcsdHeader Header;

        public NCSD(Stream stream)
        {
            Header = StructReader.ReadStruct<NcsdHeader>(stream);
        }
    }
}
